<template>
  <el-table 
    height="100%"
    ref="tableinfos" 
    :data="tableList"
  >
    <el-table-column type="index" label="序号" width="50"></el-table-column>
    <el-table-column label="商品名称" prop="drugName" width="200">
      <template v-slot="slot">
        <template v-if="slot.row.search && !readOnly">
          <searchDrug ref="searchDrug" :drugType="drugType" @select-drug="onSelectDrug" />
        </template>
        <template v-else>{{slot.row.drugName}}</template>
      </template>
    </el-table-column>
    <el-table-column label="采购规格" prop="warehousingUnit" />
    <el-table-column label="采购单位" prop="coefficientName" width="120">
      <template v-if="!readOnly" v-slot="slot">
        <template v-if="!slot.row.search">
          <el-select
            :class="{error: slot.row.errorConfig && slot.row.errorConfig.coefficientName}"
            @change="onCoefficient(slot.row, $event)"
            v-model="slot.row.coefficientName"
            :disabled="drugType === 2"
            style="width: 100px"
          >
            <template v-for="item in sactors">
              <el-option 
                :key="item.id"
                :label="item.name" 
                :value="item.name">
              </el-option>
            </template>
          </el-select>
        </template>
      </template>
    </el-table-column>
    <el-table-column label="换算系数" prop="coefficient" width="120">
      <template v-if="!readOnly" v-slot="slot">
        <template v-if="!slot.row.search">
          <el-input-number
            :class="{error: slot.row.errorConfig && slot.row.errorConfig.coefficient}"
            v-model="slot.row.coefficient"
            @blur="validatorField(slot.row, slot.column.property)"
            style="width: 100px"
            :controls="false"
            :precision="0"
            :min="0"
          />
        </template>
      </template>
    </el-table-column>
    <template v-if="drugType === 2">
      <el-table-column label="克当量" prop="equivalent" width="120">
        <template v-if="!readOnly" v-slot="slot">
          <template v-if="!slot.row.search">
            <el-input-number
              :class="{error: slot.row.errorConfig && slot.row.errorConfig.equivalent}"
              @blur="validatorField(slot.row, slot.column.property)"
              v-model="slot.row.equivalent"
              style="width: 100px"
              :controls="false"
              :min="0"
            />
          </template>
        </template>
      </el-table-column>
    </template>
    <el-table-column label="规格" prop="drugSpec" />

    <!-- 进货价 -->
    <template v-if="drugType == 1">
      <el-table-column label="KG进货价" prop="costPriceKg" width="120">
        <template v-if="!readOnly || waitConfirm" v-slot="slot">
          <template v-if="!slot.row.search">
            <el-input-number
              :class="{error: slot.row.errorConfig && slot.row.errorConfig.costPrice}"
              @change="onChangeCostPriceKG(slot.row, $event)"
              @blur="validatorField(slot.row, 'costPrice')"
              v-model="slot.row.costPriceKg"
              style="width: 100px"
              :controls="false"
              :precision="4"
              :min="0"
            />
          </template>
        </template>
      </el-table-column>
      <el-table-column :label="costPriceLabel" prop="costPrice" />
    </template>
    <template v-else>
      <el-table-column :label="costPriceLabel" prop="costPrice" width="120">
        <template v-if="!readOnly || waitConfirm" v-slot="slot">
          <template v-if="!slot.row.search">
            <el-input-number
              :class="{error: slot.row.errorConfig && slot.row.errorConfig.costPrice}"
              @change="onChangeCostPrice(slot.row, $event)"
              @blur="validatorField(slot.row, slot.column.property)"
              v-model="slot.row.costPrice"
              style="width: 100px"
              :controls="false"
              :precision="4"
              :min="0"
            />
          </template>
        </template>
      </el-table-column>
    </template>
    
    <el-table-column v-if="type == 1" label="预定数量" prop="scheduledQuantity" width="140">
      <template v-if="!readOnly" v-slot="slot">
        <template v-if="!slot.row.search">
          <div style="display: flex;align-items:center;">
          <el-input-number
            :class="{error: slot.row.errorConfig && slot.row.errorConfig.scheduledQuantity}"
            @blur="validatorField(slot.row, slot.column.property)"
            @change="onChangeQuantity(slot.row, $event)"
            v-model="slot.row.scheduledQuantity" 
            style="width: 100px"
            :controls="false"
            :precision="0"
            :min="0"
          />
          <span style="padding-left: 2px;">{{ slot.row.coefficientName }}</span>
          </div>
        </template>
      </template>
    </el-table-column>
    <el-table-column v-if="type == 0" label="入库数量" prop="actualQuantity" width="140">
      <template v-if="!readOnly" v-slot="slot">
        <template v-if="!slot.row.search">
          <el-input-number
            :class="{error: slot.row.errorConfig && slot.row.errorConfig.actualQuantity}"
            @blur="validatorField(slot.row, slot.column.property)"
            @change="onChangeActual(slot.row, $event)"
            v-model="slot.row.actualQuantity" 
            style="width: 100px"
            :controls="false"
            :precision="0"
            :min="0"
          />
          <span style="padding-left: 2px;">{{ slot.row.coefficientName }}</span>
        </template>
      </template>
    </el-table-column>
    <template v-if="showActual && type == 1">
      <el-table-column label="到货数量" prop="actualQuantity" width="120">
        <template v-if="!readOnly || waitConfirm" v-slot="slot">
          <template v-if="!slot.row.search">
            <el-input-number
              :class="{error: slot.row.errorConfig && slot.row.errorConfig.actualQuantity}"
              @blur="validatorField(slot.row, slot.column.property)"
              @change="onChangeActual(slot.row)"
              v-model="slot.row.actualQuantity"
              style="width: 100px"
              :controls="false"
              :precision="0"
              :min="0"
            />
          </template>
        </template>
      </el-table-column>
    </template>
    <el-table-column label="批次号" prop="batchNo" width="120">
      <template v-if="!readOnly || waitConfirm" v-slot="slot">
        <template v-if="!slot.row.search">
          <el-input
            :class="{error: slot.row.errorConfig && slot.row.errorConfig.batchNo}"
            @blur="validatorField(slot.row, slot.column.property)"
            v-model="slot.row.batchNo"
          />
        </template>
      </template>
    </el-table-column>
    <template v-if="(drugType == 7 || drugType === 2) && type == 0">
      <el-table-column label="有效期" prop="termOfValidity" width="145">
        <template v-if="!readOnly" v-slot="slot">
          <template v-if="!slot.row.search">
            <el-date-picker
              :class="{error: slot.row.errorConfig && slot.row.errorConfig.termOfValidity}"
              v-model="slot.row.termOfValidity"
              @change="validatorField(slot.row, slot.column.property)"
              type="date"
              placeholder="选择日期"
              value-format="yyyy-MM-dd"
              style="width: 135px"
              :picker-options="pickerOptions"
            />
          </template>
        </template>
      </el-table-column>
    </template>
    <el-table-column label="商品总价" prop="commodityPrice">
      <template v-slot="slot">
        <template v-if="!slot.row.search">{{ formatMoney(slot.row.commodityPrice) }}</template>
      </template>
    </el-table-column>
    <el-table-column v-if="drugType === 2" label="红冲" prop="redPun" width="120">
      <template v-slot="slot">
        <template v-if="!slot.row.search">
          <el-input-number
            v-if="editRedPun"
            :class="{error: slot.row.errorConfig && slot.row.errorConfig.redPun}"
            v-model="slot.row.redPun"
            @change="onChangeRedPun(slot.row, $event)"
            @blur="validatorField(slot.row, slot.column.property)"
            style="width: 80px"
            placeholder="100%"
            :controls="false" 
            :precision="0"
            :max="100"
            :min="0"
          />
          <span v-if="editRedPun">%</span>
          <span v-if="!editRedPun">{{ slot.row.redPun }}%</span>
        </template>
      </template>
    </el-table-column>
    <el-table-column v-if="drugType === 2" label="成本价" prop="selfPrice" width="120">
      <template v-if="!readOnly" v-slot="slot">
        <template v-if="!slot.row.search">
          <el-input-number
            v-if="slot.row.drugType === 2"
            :class="{error: slot.row.errorConfig && slot.row.errorConfig.selfPrice}"
            v-model="slot.row.selfPrice"
            @blur="validatorField(slot.row, slot.column.property)"
            style="width: 100px"
            :controls="false"
            :disabled="true"
            :precision="4"
            :min="0"
          />
          <span v-else>{{ slot.row.selfPrice }}</span>
        </template>
      </template>
    </el-table-column>
    <el-table-column v-if="drugType === 2" label="成本总价" prop="commoditySelfPrice">
      <template v-slot="slot">
        <template v-if="!slot.row.search">{{ formatMoney(slot.row.commoditySelfPrice) }}</template>
      </template>
    </el-table-column>
    <el-table-column label="入库总数量" prop="totalQuantity">
      <template v-slot="slot">
        <template v-if="!slot.row.search">
          <span>{{ slot.row.coefficient * slot.row.actualQuantity }}</span>
        </template>
      </template>
    </el-table-column>
    <template v-if="!readOnly">
      <el-table-column label="操作">
        <template v-slot="slot">
          <template v-if="!slot.row.search">
            <el-button type="text" @click="onDel(slot.$index)">删除</el-button>
          </template>
        </template>
      </el-table-column>
    </template>
  </el-table>
</template>

<script>
import { parseTime, formatMoney } from "@/utils/index";
import Validator from "async-validator";
import searchDrug from "./search";

export default {
  name: "infoFormTable",
  props: {
    // 药品类型 1-饮片,2-颗粒剂，7-西药及中成药
    drugType: {
      type: Number,
      required: true
    },
    // 换算系数
    sactors: {
      type: Array,
      default() {
        return [];
      }
    },
    // 只读
    readOnly: {
      type: Boolean,
      default: false // 默认可编辑
    },
    // 待确认
    waitConfirm: {
      type: Boolean,
      default: false
    },
    // 展示实际入库数量
    showActual: {
      type: Boolean,
      default: false
    },
    // 红冲可编辑
    editRedPun: {
      type: Boolean,
      default: true
    },
    // 0-入库, 1-采购计划
    type: {
      type: Number,
      default: 0
    },
    // 入库方式
    wareHousingType: {
      type: Number,
      default: 0
    },
  },
  components: { searchDrug },
  data() {
    return {
      pickerOptions: {
        disabledDate(d) {
          let time = new Date();
          return d.getTime() < time.getTime();
        }
      },
      rules: {
        coefficientName: {
          type: 'string',
          required: true,
          message: '请选择采购单位'
        },
        coefficient: {
          type: 'number',
          required: true,
          validator(rule, value, callback) {
            if(!value) {
              callback(new Error("请填写换算系数"));
            }
            if(value <= 0) {
              callback(new Error("换算系数必须大于0"));
            }
            callback();
          },
        },
        costPrice: {
          type: 'number',
          required: true,
          message: '请填写进货价',
          validator(rule, value, callback) {
            if(!rule.required) {
              callback();
            } else if(!value) {
              callback(new Error("请填写进货价"));
            } else if(value <= 0) {
              callback(new Error("进货价必须大于0"));
            } else {
              callback();
            }
          },
        },
        scheduledQuantity: {
          type: 'number',
          required: true,
          validator(rule, value, callback) {
            if(!value) {
              callback(new Error("请填写预定数量"));
            } else if(value <= 0) {
              callback(new Error("预定数量必须大于0"));
            } else {
              callback();
            }
          },
        },
        actualQuantity: {
          type: 'number',
          required: false,
          validator(rule, value, callback) {
            if(!rule.required) {
              callback();
            }
            if(!value || value === 0) {
              callback(new Error("请填写实际入库数量"));
            }
            if(value <= 0) {
              callback(new Error("实际入库必须大于0"));
            }
            callback();
          },
        },
        batchNo: {
          type: 'string',
          required: true,
          message: '请填写批次号',
        },
        termOfValidity: {
          type: 'string',
          required: false,
          message: '请选择有效期'
        },
        redPun: {
          type: 'number',
          required: false,
          message: '请填写红冲',
        },
        equivalent: {
          type: 'number',
          required: false,
          message: '请填写克当量',
        },
      },
      listener: null,
      validObj: {},
      tableList: [],
    }
  },
  watch: {
    wareHousingType() {
      // 调拨入库、赠品入库 进货价非必填
      if(this.wareHousingType === 4 || this.wareHousingType === 5) {
        this.rules.costPrice.required = false;
      } else {
        this.rules.costPrice.required = true;
      }
    }
  },
  computed: {
    costPriceLabel() {
      if(this.drugType === 2 || this.drugType === 1) {
        return "G进货价";
      }
      return "进货价";
    }
  },
  created() {
    this.listener = (e) => {
      this.onKeyup(e);
    }
    document.addEventListener("keyup", this.listener);
  },
  beforeDestroy() {
    document.removeEventListener("keyup", this.listener);
  },
  mounted() {
    // 待确认和入库，实际入库必填
    if(this.waitConfirm || this.type === 0) {
      this.rules.actualQuantity.required = true;
    }
    
    if(this.type == 1) {
      // 采购计划，批次号可不填
      this.rules.batchNo.required = false;
    }

    // 入库，颗粒剂有效期必填
    if(this.drugType === 2 && this.type == 0) {
      this.rules.termOfValidity.required = true;
    }
    
    // 调拨入库、赠品入库 进货价非必填
    if(this.wareHousingType === 4 || this.wareHousingType === 5) {
      this.rules.costPrice.required = false;
    } else {
      this.rules.costPrice.required = true;
    }

    // 颗粒剂，克当量必填
    if(this.drugType === 2) {
      this.rules.equivalent.required = true;
    }
  },
  methods: {
    formatMoney,
    parseTime,
    onSelectDrug(row) {
      let list = this.tableList.filter(item => {
        return row.id == item.drugId;
      });
      if(list.length > 0) {
        this.$message.error('所选药品已添加!');
        return;
      }
      let data = {
        batchNo: "",
        costPrice: 0,
        selfPrice: 0,
        redPun: 0,
        createTime: "",
        packageUnit: row.packageUnit,
        drugId: row.id,
        drugManufactor: row.drugManufactor,
        drugName: row.drugName,
        drugSpec: row.drugSpec,
        leftCount: 0,
        mothUse: 0,
        pharmacyId: "",
        salePrice: row.salePrice,
        equivalent: row.drugEquivalent,
        stock: row.stock,
        termOfValidity: "",
        wareHousingNo: "",
        drugType: row.drugType,
        coefficientName: null,
        coefficient: row.coefficient,
        commodityPrice: 0,
        scheduledQuantity: 0,
        actualQuantity: 0,
        commoditySelfPrice: 0,
        warehousingUnit: row.coefficientName, // 采购规格
      };
      // 饮片默认kg，颗粒剂默认瓶
      if(this.drugType == 1) {
        this.onCoefficient(data, "kg");
      } else if(this.drugType == 2) {
        data.coefficientName = "瓶";
        // 颗粒剂红冲默认75
        data.redPun = 75;
      }
      this.tableList.splice(this.tableList.length - 1, 0, data);
      // 禁止切换药品类型
      this.$emit("disabled", true);
    },
    onChangeCostPrice(row, costPrice) {
      // 进货价 = 进货价 * 红冲百分比 + 成本价
      // 成本价 = 进货价(1 - 红冲百分比)
      row.costPrice = costPrice;
      if(row.redPun >= 0 && costPrice >= 0) {
        row.selfPrice = row.costPrice * (1 - row.redPun/100);
        if(row.actualQuantity > 0) {
          row.commoditySelfPrice = row.selfPrice * row.actualQuantity;
        }
      }
      if(row.actualQuantity > 0 && costPrice >= 0) {
        row.commodityPrice = row.costPrice * row.actualQuantity;
        this.$emit("onChangeTotalPrice");
      }
    },
    onChangeCostPriceKG(row, price) {
      // 进货价 = 进货价 * 红冲百分比 + 成本价
      // 成本价 = 进货价(1 - 红冲百分比)
      let costPrice = null;
      if(price) {
        costPrice = price / row.coefficient;
      }
      row.costPrice = costPrice;
      if(row.redPun >= 0 && costPrice >= 0) {
        row.selfPrice = costPrice * (1 - row.redPun/100);
        if(row.actualQuantity > 0) {
          row.commoditySelfPrice = row.selfPrice * row.actualQuantity * row.coefficient;
        }
      }
      if(row.actualQuantity > 0 && costPrice >= 0) {
        row.commodityPrice = costPrice * row.actualQuantity * row.coefficient;
        this.$emit("onChangeTotalPrice");
      }
    },
    onChangeRedPun(row, redPun) {
      row.redPun = redPun;
      if(row.costPrice > 0 && redPun >= 0) {
        row.selfPrice = row.costPrice * (1 - row.redPun/100);
        if(row.scheduledQuantity > 0) {
          row.commoditySelfPrice = row.selfPrice * row.scheduledQuantity;
        }
      }
    },
    onChangeQuantity(row) {
      if(row.scheduledQuantity >= 0) {
        row.actualQuantity = row.scheduledQuantity;
        if(row.costPrice > 0) {
          if(this) {

          }
          row.commodityPrice = row.costPrice * row.scheduledQuantity;
          if(this.drugType == 1) row.commodityPrice *= row.coefficient;
          this.$emit("onChangeTotalPrice");
        }
        if(row.selfPrice > 0) {
          row.commoditySelfPrice = row.selfPrice * row.scheduledQuantity;
          if(this.drugType == 1) row.commoditySelfPrice *= row.coefficient;
        }
      }
    },
    onChangeActual(row) {
      if(row.actualQuantity >= 0) {
        if(row.costPrice > 0) {
          row.commodityPrice = row.costPrice * row.actualQuantity;
          if(this.drugType == 1) row.commodityPrice *= row.coefficient;
          this.$emit("onChangeTotalPrice");
        }
        if(row.selfPrice > 0) {
          row.commoditySelfPrice = row.selfPrice * row.actualQuantity;
          if(this.drugType == 1) row.commoditySelfPrice *= row.coefficient;
        }
        if(this.type == 0) {
          row.scheduledQuantity = row.actualQuantity;
        }
      }
    },
    getSelectRows() {
      let res = this.tableList.filter(item => {
        return !item.search;
      });
      return res;
    },
    onDel(index) {
      this.tableList.splice(index, 1);
      if(this.tableList.length === 1) {
        // 药品被清空？允许切换药品类型
        this.$emit("disabled", false);
      }
      this.$emit("onChangeTotalPrice");
    },
    setTableList(list) {
      if(this.drugType === 1) {
        // 饮片，计算kg进货价
        list.forEach(item => {
          item.costPriceKg = item.costPrice * item.coefficient;
        });
      }
      this.tableList = list;
      this.$nextTick(() => {
        this.tableList.forEach(item => {
          if(!item.search) {
            this.$refs.tableinfos.toggleRowSelection(item, true);
          }
        });
      });
      this.$emit("onChangeTotalPrice");
    },
    onCoefficient(row, value) {
      let data = this.sactors.filter(item => {
        return item.name == value;
      });
      if(data.length > 0) {
        row.coefficientName = value;
        row.coefficient = data[0].coefficient;
      }
      this.validatorField(row, "coefficientName");
    },
    validator(call) {
      let selectList = this.getSelectRows();
      let rules = this.rules;
      let v = new Validator(rules);
      this.validObj.count = 0;
      this.validObj.backCall = call;
      this.validObj.errors = [];
      selectList.forEach((item, index) => {
        this._validatorItem(item, index, v);
      });
      if(selectList.length == 0) {
        this.validObj.backCall(false, this.validObj.errors);
      }
    },
    validatorField(row, fileid) {
      if(!this.rules[fileid] || !this.rules[fileid].required) return;
      let rules = {
        [fileid]: this.rules[fileid]
      };
      let v = new Validator(rules);
      let obj = {
        [fileid]: row[fileid]
      }
      v.validate(obj, (errors, fileds) => {
        if(errors) {
          this._setErrorStyle(row, fileid, true);
        } else {
          this._setErrorStyle(row, fileid, false);
        }
      });
    },
    onKeyup(e) {
      if(e.keyCode === 13 && this.$refs.searchDrug) {
        this.validator(error => {
          if(!error) {
            this.$refs.searchDrug.focus();
          }
        });
      }
    },
    // 计算总库存,入库数量*换算系数*瓶当量，非颗粒剂瓶当量默认为1 
    // 已废弃的函数
    _calcQuantity(row) {
      // let { coefficient, drugType, actualQuantity, equivalent, scheduledQuantity } = row;
      // let quantity = actualQuantity || scheduledQuantity;

      // // 导入的实际入库数量是null值，需要初始化
      // if(!row.actualQuantity) {
      //   row.actualQuantity = quantity;
      // }

      // if(drugType === 2 && equivalent > 0) {
      //   return Math.ceil(coefficient * quantity * equivalent);
      // }
      // return coefficient * quantity;
    },
    _validatorItem(item, index, v) {
      let selectList = this.getSelectRows();
      v.validate(item, (errors, fileds) => {
        this.validObj.count ++;
        if(errors) {
          this.validObj.errors.push({ index, fileds });
        }
        for(let filed in item) {
          if(fileds && fileds[filed]) {
            this._setErrorStyle(item, filed, true);
          } else {
            this._setErrorStyle(item, filed, false);
          }
        }
        if(selectList.length === this.validObj.count) {
          this.validObj.backCall(this.validObj.errors.length > 0 ,this.validObj.errors);
        }
      });
    },
    _setErrorStyle(row, fileid, error) {
      let errorConfig = row.errorConfig;
      if(!errorConfig) {
        errorConfig = {};
        this.$set(row, "errorConfig", errorConfig);
      }
      this.$set(errorConfig, fileid, error);
    }
  }
}
</script>